﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.Graphics;
using Android.OS;
using Android.Text;
using Android.Views;
using Android.Widget;
namespace SCPAK2
{
    [Activity(Label = "BlocksData编辑器", Theme = "@style/AppTheme")]
    public class BlockEditActivity : Activity
    {
        public static Dictionary<string, string> tranlates = new Dictionary<string, string>();
        private TextView title;
        private Spinner spinner;
        private MyDialog dialog;
        private Button button,addnewLine,delnewline;
        public LinearLayout containView;
        public List<List<string>> blocklist = new List<List<string>>();
        private int lastClickPos = 0;
        private List<Action> Dispatch = new List<Action>();
        private ArrayAdapter arrayAdapter;
        public void initTranslate()
        {
            if (tranlates.Count > 0)
            {
                return;
            }
            tranlates.Add("Class Name", "源码类名");
            tranlates.Add("DefaultDisplayName", "默认显示名称");
            tranlates.Add("DefaultCategory", "默认类别");
            tranlates.Add("Behaviors", "方块行为");
            tranlates.Add("DisplayOrder", "显示顺序");
            tranlates.Add("DefaultIconBlockOffset", "默认图标块偏移");
            tranlates.Add("DefaultIconViewOffset", "默认图标视图偏移");
            tranlates.Add("DefaultIconViewScale", "默认图标视图缩放");
            tranlates.Add("FirstPersonScale", "第一人称缩放");
            tranlates.Add("FirstPersonOffset", "第一人称偏移");
            tranlates.Add("FirstPersonRotation", "第一人称旋转");
            tranlates.Add("InHandScale", "手持缩放");
            tranlates.Add("InHandOffset", "手持偏移");
            tranlates.Add("InHandRotation", "手持旋转");
            tranlates.Add("CraftingId", "合成谱标识");
            tranlates.Add("DefaultCreativeData", "默认为创造数据");
            tranlates.Add("IsCollidable", "是否可碰撞");
            tranlates.Add("IsPlaceable", "是可放置");
            tranlates.Add("IsDiggingTransparent", "挖掘是否透明");
            tranlates.Add("IsPlacementTransparent", "放置是否透明");
            tranlates.Add("DefaultIsInteractive", "是否可交互");
            tranlates.Add("IsEditable", "是否可编辑");
            tranlates.Add("IsNonDuplicable", "是否可堆叠");
            tranlates.Add("IsGatherable", "是否可收集");
            tranlates.Add("HasCollisionBehavior", "是否有碰撞行为");
            tranlates.Add("KillsWhenStuck", "卡住是否会死亡");
            tranlates.Add("IsFluidBlocker", "是否阻挡流体扩散");
            tranlates.Add("IsTransparent", "方块面是否透明");
            tranlates.Add("DefaultShadowStrength", "默认阴影强度");
            tranlates.Add("LightAttenuation", "光衰减强度");
            tranlates.Add("DefaultEmittedLightAmount", "默认发光强度");
            tranlates.Add("ObjectShadowStrength", "物体阴影强度");
            tranlates.Add("DefaultDropContent", "默认掉落内容");
            tranlates.Add("DefaultDropCount", "默认掉落数量");
            tranlates.Add("DefaultExperienceCount", "默认掉落经验");
            tranlates.Add("RequiredToolLevel", "所需工具级别");
            tranlates.Add("MaxStacking", "最大堆积");
            tranlates.Add("SleepSuitability", "适合睡眠系数");
            tranlates.Add("FrictionFactor", "摩擦系数");
            tranlates.Add("Density", "密度");
            tranlates.Add("NoAutoJump", "是否禁止自动跳跃");
            tranlates.Add("NoSmoothRise", "是否非平稳上升");
            tranlates.Add("FuelHeatLevel", "燃料加热等级");
            tranlates.Add("FuelFireDuration", "燃料持续时间");
            tranlates.Add("DefaultSoundMaterialName", "默认声音材质名称");
            tranlates.Add("ShovelPower", "铲子效率");
            tranlates.Add("QuarryPower", "稿子效率");
            tranlates.Add("HackPower", "斧子效率");
            tranlates.Add("DefaultMeleePower", "默认近战攻击力");
            tranlates.Add("DefaultMeleeHitProbability", "默认近战命中概率");
            tranlates.Add("DefaultProjectilePower", "默认射击攻击力");
            tranlates.Add("ToolLevel", "工具等级");
            tranlates.Add("PlayerLevelRequired", "需要玩家等级");
            tranlates.Add("Durability", "耐久");
            tranlates.Add("IsAimable", "是否可瞄准");
            tranlates.Add("IsStickable", "是否可粘上物体");
            tranlates.Add("AlignToVelocity", "与速度对齐");
            tranlates.Add("ProjectileSpeed", "投掷速度");
            tranlates.Add("ProjectileDamping", "投掷阻力");
            tranlates.Add("ProjectileTipOffset", "投掷倾摆");
            tranlates.Add("DisintegratesOnHit", "击中后消失");
            tranlates.Add("ProjectileStickProbability", "投掷粘上概率");
            tranlates.Add("DefaultHeat", "默认热量");
            tranlates.Add("FireDuration", "燃烧持续时间");
            tranlates.Add("ExplosionResilience", "爆炸抗性");
            tranlates.Add("DefaultExplosionPressure", "默认爆炸压力");
            tranlates.Add("DefaultExplosionIncendiary", "默认爆炸燃烧弹");
            tranlates.Add("IsExplosionTransparent", "爆炸透明");
            tranlates.Add("DigMethod", "挖掘方法");
            tranlates.Add("DigResilience", "挖掘抗性");
            tranlates.Add("ProjectileResilience", "投掷抗性");
            tranlates.Add("DefaultNutritionalValue", "默认营养值");
            tranlates.Add("DefaultSicknessProbability", "默认患病概率");
            tranlates.Add("FoodType", "食物类型");
            tranlates.Add("DefaultRotPeriod", "默认腐烂周期");
            tranlates.Add("DefaultTextureSlot", "默认纹理位置");
            tranlates.Add("DestructionDebrisScale", "掉落缩放");
            tranlates.Add("DefaultDescription", "默认描述");
            tranlates.Add("MaxInHandStacking", "最大手持堆叠");
            tranlates.Add("EmittedLightAmount", "发光强度");
        }
        protected override void OnCreate(Bundle savedInstanceState)
        {
            initTranslate();
            base.OnCreate(savedInstanceState);
            SetContentView(Resource.Layout.block_edit);
            dialog = new MyDialog(this);
            arrayAdapter = new ArrayAdapter(this, Resource.Layout.spinner_item, Resource.Id.message);
            Bundle config = Intent.GetBundleExtra("file");
            string fullname = config.GetString("fullname");
            string name = config.GetString("name");
            delnewline = FindViewById<Button>(Resource.Id.block_del_line);
            addnewLine = FindViewById<Button>(Resource.Id.block_add_line);
            title = FindViewById<TextView>(Resource.Id.block_edit_title);
            spinner = FindViewById<Spinner>(Resource.Id.block_edit_spinner);
            containView = FindViewById<LinearLayout>(Resource.Id.containView);
            button = FindViewById<Button>(Resource.Id.block_edit_save);
            button.Click += new EventHandler(saveFile);
            addnewLine.Click += new EventHandler(AddLine);
            delnewline.Click += new EventHandler(DelLine);
            spinner.Adapter = arrayAdapter;
            spinner.ItemSelected += new EventHandler<AdapterView.ItemSelectedEventArgs>(spinnerClick);
            spinner.Clickable = true;
            title.Text = $"{fullname}";
            using (StreamReader stream = new StreamReader(File.OpenRead(fullname)))
            {
                string content = stream.ReadToEnd();
                if (!checkValid(content))
                {
                    ShowMsg("错误", "不是有效的BlocksData文件");
                }
                else
                {
                    parseBlocks(content);
                    parseToView();
                }
            }
        }
        public void ShowMsg(string title,string message) {
            dialog.setText(title, message);
            dialog.Show();
        }
        public void AddLine(object obj, EventArgs args) {
            if (blocklist.Count > 0)
            {
                List<string> vs = new List<string>();
                vs.AddRange(blocklist[lastClickPos]);
                blocklist.Add(vs);
                lastClickPos = blocklist.Count - 1;
                parseToView();
            }
            else
            {
                tip("请先载入模板数据");
            }
        }
        public void DelLine(object obj, EventArgs args)
        {
            if (blocklist.Count > 0 && lastClickPos > 0)
            {
                blocklist.RemoveAt(lastClickPos);
                if (lastClickPos >= blocklist.Count) lastClickPos = 0;
                parseToView();
            }
            else
            {
                tip("禁止清空数据");
            }
        }
        public void tip(string txt)
        {
            Toast.MakeText(this, txt, ToastLength.Long).Show();
        }
        public void saveFile(object obj, EventArgs args)
        {
            Bundle config = Intent.GetBundleExtra("file");
            string fullname = config.GetString("fullname");
            StringBuilder stringBuilder = new StringBuilder();
            int yy = 0;
            foreach (List<string> items in blocklist)
            {
                int dd = 0;
                foreach (string item in items)
                {
                    stringBuilder.Append(item);
                    if (dd++ < items.Count() - 1)
                    {
                        stringBuilder.Append(';');
                    }
                }
                if (yy++ < blocklist.Count() - 1)
                {
                    stringBuilder.Append('\n');
                }
            }
            string newfile = System.IO.Path.GetFileNameWithoutExtension(fullname) + "_new" + System.IO.Path.GetExtension(fullname);
            SaveFile(System.IO.Path.GetDirectoryName(fullname),newfile,stringBuilder.ToString());
        }

        public void SaveFile(string basepath, string filename,string content) {
            string abpath = System.IO.Path.Combine(basepath, filename);
            try
            {
                File.WriteAllText(abpath, content);
                tip("已保存到该目录的新文件" + filename);
            }
            catch (Exception e)
            {
                dialog.SetEditText("错误", "保存失败，文件被占用，请重试", filename, (text) => {
                    if (string.IsNullOrEmpty(text))
                    {
                        tip("禁止为空");
                    }
                    else SaveFile(basepath, text, content);
                });
                dialog.Show();
            }
        }

        public void textChange(object obj, TextChangedEventArgs args)
        {
            if (lastClickPos < blocklist.Count) {
                EditText edit = (EditText)obj;
                int posaa = (int)edit.Tag;
                string soo = edit.Text.ToString();
                if (soo != blocklist[lastClickPos][posaa])
                {
                    blocklist[lastClickPos][posaa] = soo;
                }
            }
        }
        public void refreshView(int where)
        { //根据spinner选择的pos绘制视图
            int ii = 0;
            containView.RemoveAllViews();
            foreach (string item in blocklist[where])
            {
                LinearLayout linearLayout = new LinearLayout(this);
                linearLayout.Orientation = Orientation.Horizontal;
                linearLayout.LayoutParameters = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.WrapContent) { BottomMargin = 4 };
                RelativeLayout relativeLayout = new RelativeLayout(this);
                relativeLayout.LayoutParameters = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.MatchParent, 1f);
                EditText editText = new EditText(this);
                BlockSpinnerAdapter spinnerAdapter = new BlockSpinnerAdapter(this);
                Spinner spinner = new Spinner(this);
                spinner.LayoutParameters = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.MatchParent) { LeftMargin = 1 };
                spinner.Adapter = spinnerAdapter;
                TextView textView = new TextView(this);
                tranlates.TryGetValue(blocklist[0][ii], out string title);
                if (string.IsNullOrEmpty(title))
                {
                    title = blocklist[0][ii];
                }
                textView.Text = title;
                textView.Gravity = GravityFlags.Center;
                textView.LayoutParameters = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.MatchParent, 1f);
                textView.SetTextColor(Color.ParseColor("#ffffff"));
                textView.SetBackgroundColor(Color.ParseColor("#000000"));
                editText.Tag = ii;
                editText.SetBackgroundColor(Color.ParseColor("#000000"));
                editText.SetTextColor(Color.ParseColor("#ffffff"));
                editText.LayoutParameters = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.MatchParent) { LeftMargin = 1 };
                editText.Gravity = GravityFlags.Center;
                spinner.Tag = ii;
                if ((item.ToLower() == "true" || item.ToLower() == "false")) {
                    spinner.Visibility = ViewStates.Visible;
                    if (item.ToLower() == "true")
                    {
                        spinnerAdapter.Add("TRUE");
                        spinnerAdapter.Add("FALSE");
                    }
                    else
                    {
                        spinnerAdapter.Add("FALSE");
                        spinnerAdapter.Add("TRUE");
                    }
                    spinnerAdapter.NotifyDataSetChanged();
                }
                else spinner.Visibility = ViewStates.Invisible;
                editText.Visibility = spinner.Visibility == ViewStates.Visible ? ViewStates.Invisible : ViewStates.Visible;
                editText.Text = item;
                linearLayout.AddView(textView);
                linearLayout.AddView(relativeLayout);
                relativeLayout.AddView(editText);
                relativeLayout.AddView(spinner);
                containView.AddView(linearLayout);
                editText.TextChanged += new EventHandler<TextChangedEventArgs>(textChange);
                spinner.ItemSelected += new EventHandler<AdapterView.ItemSelectedEventArgs>(spinnerClick2);
                ++ii;
            }
            for (int i=0;i<Dispatch.Count;i++) {
                Dispatch[i]();
            }
            Dispatch.Clear();
        }
        public void spinnerClick2(object obj, AdapterView.ItemSelectedEventArgs args) {

            Spinner spinner = (Spinner)obj;
            int posaa = (int)spinner.Tag;
            string soo = (string)spinner.Adapter.GetItem(args.Position);
            if (spinner.Visibility == ViewStates.Visible && soo != blocklist[lastClickPos][posaa])
            {
                blocklist[lastClickPos][posaa] = soo;
            }
        }
        public void spinnerClick(object obj, AdapterView.ItemSelectedEventArgs args)
        {
            lastClickPos = args.Position;//处理位置
            refreshView(lastClickPos);
        }
        public bool checkValid(string content)
        {
            if (content.Contains(";"))
            {
                string[] ll = content.Split(new char[] { ';' });
                if (ll.Length > 10)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            return false;
        }
        public void parseToView()
        {
            arrayAdapter.Clear();
            foreach (List<string> item in blocklist)
            {
                arrayAdapter.Add($"[{item[0]}]{item[1]}");
            }
            refreshView(lastClickPos);
            arrayAdapter.NotifyDataSetChanged();
        }
        public override void OnBackPressed()
        {
            Finish();
        }
        //解析文件
        public List<List<string>> parseBlocks(string content)
        {
            string[] lines = null;
            if (content.Contains("\r\n"))
            {
                lines = content.Split(new string[] { "\r\n" }, StringSplitOptions.None);
            }
            else
            {
                lines = content.Split(new string[] { "\n" }, StringSplitOptions.None);
            }

            for (int i= 0;i < lines.Length;i++)
            {
                string blockline=lines[i];
                string[] items = blockline.Split(new char[] { ';' });
                if (items.Length > 2)
                {
                    if (string.IsNullOrEmpty(items[0]))
                    {
                        if (string.IsNullOrEmpty(items[1]) && string.IsNullOrEmpty(items[2]))
                            continue;//去除空的
                        else items[i]="Class Name";
                    }
                }

                List<string> block = new List<string>();
                foreach (string item in items)
                {
                    block.Add(item);
                }
                if (block.Count > 10)
                {
                    blocklist.Add(block);
                }
            }
            return blocklist;
        }
    }
}